// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <algorithm>

#include <QApplication>
#include <QLabel>
#include <QGridLayout>
#include <QSlider>

#include "QvisMultiresControlWindow.h"
#include <DebugStream.h>
#include <FileServerList.h>
#include <MultiresControlAttributes.h>


// ****************************************************************************
// Method: QvisMultiresControlWindow::QvisMultiresControlWindow
//
// Purpose:
//   Constructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

QvisMultiresControlWindow::QvisMultiresControlWindow(const int type,
                         MultiresControlAttributes *subj,
                         const QString &caption,
                         const QString &shortName,
                         QvisNotepadArea *notepad)
    : QvisOperatorWindow(type,subj, caption, shortName, notepad),
      resolution(NULL),
      resolutionLevelLabel(NULL)
{
    atts = subj;
    fileServer->Attach(this);
}


// ****************************************************************************
// Method: QvisMultiresControlWindow::~QvisMultiresControlWindow
//
// Purpose:
//   Destructor
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

QvisMultiresControlWindow::~QvisMultiresControlWindow()
{
  if(fileServer) {
    fileServer->Detach(this);
  }
}


// ****************************************************************************
// Method: QvisMultiresControlWindow::CreateWindowContents
//
// Purpose:
//   Creates the widgets for the window.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//
//   Tom Fogal, Mon Aug 30 12:30:54 MDT 2010
//   Add resolution # to label.
//
//   Brad Whitlock, Wed Sep  2 17:54:16 PDT 2020
//   Use valueChanged to set the label text. Use sliderReleased to update the
//   multires value. This makes autoupdate work better.
//
// ****************************************************************************

void
QvisMultiresControlWindow::CreateWindowContents()
{
    QGridLayout *mainLayout = new QGridLayout(NULL);
    topLayout->addLayout(mainLayout);

    resolutionLevelLabel = new QLabel(this);
    mainLayout->addWidget(resolutionLevelLabel,0,0);
    UpdateLabelText(0);

    this->resolution = new QSlider(Qt::Horizontal, this);
    this->resolution->setMaximum(32); // HACK, we don't know yet.
    this->resolution->setValue(0);
    mainLayout->addWidget(this->resolution, 0, 1);

    connect(this->resolution, SIGNAL(valueChanged(int)), this,
            SLOT(updateResolutionLevelLabel(int)));
    connect(this->resolution, SIGNAL(sliderReleased()), this,
            SLOT(resolutionLevelChanged()));
}


// ****************************************************************************
// Method: QvisMultiresControlWindow::UpdateWindow
//
// Purpose:
//   Updates the widgets in the window when the subject changes.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//
//   Tom Fogal, Mon Aug 30 12:30:28 MDT 2010
//   Include resolution # in label.
//
// ****************************************************************************

void
QvisMultiresControlWindow::UpdateWindow(bool doAll)
{
    QString temp;

    if(fileServer)
    {
        const avtDatabaseMetaData *md = fileServer->GetMetaData(
          fileServer->GetOpenFile(),
          GetStateForSource(fileServer->GetOpenFile()), true, true
        );
        if(md && md->GetNumMeshes() != 0)
        {
            const avtMeshMetaData* mmd = md->GetMesh(0);
            debug3 << "Mesh says there are " << mmd->LODs
                   << " levels of detail.\n";
            atts->SetMaxResolution(mmd->LODs);
        }
    }
    else
    {
        debug1 << "No file server, bailing...\n";
    }
    debug1 << atts->GetMaxResolution() << " levels of detail available.\n";

    this->resolution->blockSignals(true);
    this->resolution->setValue(atts->GetResolution());
    this->resolution->setMaximum(std::max(0, atts->GetMaxResolution()));
    this->resolution->blockSignals(false);
    this->resolution->update();
    UpdateLabelText(atts->GetResolution());
    // set it back to its default background color.
    QPalette p = QApplication::palette();
    this->resolutionLevelLabel->setPalette(p);
}


// ****************************************************************************
// Method: QvisMultiresControlWindow::GetCurrentValues
//
// Purpose:
//   Gets values from certain widgets and stores them in the subject.
//
// Note:       Autogenerated by xml2window.
//
// Programmer: xml2window
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
QvisMultiresControlWindow::GetCurrentValues(int which_widget)
{
    bool doAll = (which_widget == -1);
    QString msg, temp;

    // Do resolution
    if(which_widget == MultiresControlAttributes::ID_resolution || doAll)
    {
        atts->SetResolution(this->resolution->value());
    }
}

// ****************************************************************************
// Method: QvisMultiresControlWindow::UpdateLabelText
//
// Purpose:
//   Update the resolution label text.
//
// Arguments:
//   value : The value we want to put into the text.
//
// Returns:    
//
// Note:       
//
// Programmer: Brad Whitlock
// Creation:   Wed Sep  2 18:28:45 PDT 2020
//
// Modifications:
//
// ****************************************************************************

void
QvisMultiresControlWindow::UpdateLabelText(int value)
{
    // Adjust padding so the width does not change so much that the slider moves
    // because the label changed sizes.
    QString res, space(" ");
    res.setNum(value);
    if(value < 100)
        res = space + res;
    if(value < 10)
        res = space + res;
    resolutionLevelLabel->setText(tr("Resolution: %1").arg(res));
}

//
// Qt Slot functions
//

// Modificatons:
//
//   Tom Fogal, Mon Aug 30 12:52:36 MDT 2010
//   Change resolution label as well.
//
//   Brad Whitlock, Wed Sep  2 18:07:03 PDT 2020
//   Only set the label values here.
void
QvisMultiresControlWindow::updateResolutionLevelLabel(int val)
{
    if(val != atts->GetResolution())
    {
        UpdateLabelText(val);
        resolutionLevelLabel->setAutoFillBackground(true);
        // Change the text color to indicate there would be unapplied changes.
        QPalette p;
        p.setColor(QPalette::WindowText, QColor(0,228,0));
        resolutionLevelLabel->setPalette(p);
    }
}

void
QvisMultiresControlWindow::resolutionLevelChanged()
{
    int val = resolution->value();

    if(val != atts->GetResolution())
    {
        UpdateLabelText(val);
        atts->SetResolution(val);
        SetUpdate(false);
        Apply();
    }
}
